﻿// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

using Furion.DatabaseAccessor;
using Furion.DynamicApiController;
using Neto.Db.SqlSugar;
using Neto.Db.SqlSugar.Paged;
using System.Text.RegularExpressions;

namespace Neto.Application.Api;

/// <summary>
/// IP限制
/// </summary>
[Authorize]//jwt授权
[ApiDescriptionSettings("Api", Name = "SysIpLimit")]
//[MaApi(controller: "SysIpLimit", controllerDescription: "IP限制", PCode = "Api")]
[ApiArea("Api")]
[PgApiController("IP白名单服务", MenuPCode = "Sys_Setting")]
[PgApiMenu("IP白名单", "sys-setting_ip-whitelist",MenuPCode = "Sys_Setting",Icon = "heroicons:lock-closed")]
//[Route("Api/[controller]/[action]")]
public class ApiSysIpLimitService(ISqlSugarClient db)
:  IDynamicApiController
{


    /// <summary>
    /// 新增一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [PgApiAction(name: "新增一条")]
    [OperationId(nameof(Insert))]
    [HttpPost]
    public async Task<long> Insert(ApiSysIpLimitInput input)
    {
        ////验证 父级下 唯一 Key是否存在
        //var isexit = await db.Queryable<SysIpLimit>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key);
        //if (isexit)
        //{
        //    throw Oops.Bah("唯一标识Key不能重复");
        //}
        var addentity = input.Adapt<SysIpLimit>();

        //IpV4 验证\IP段是否存在于其它IP段中
        addentity = await IpV4Validate(addentity, input);

        return await db.InsertRsIdAsync(addentity);
    }

    /// <summary>
    /// 更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [PgApiAction(name: "更新一条")]
    [OperationId(nameof(Update))]
    [HttpPost]
    public async Task<bool> Update(ApiSysIpLimitInput input)
    {
        ////验证 父级下 唯一 Key是否存在
        //var isexit = await db.Queryable<SysIpLimit>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key && o.Id != input.Id);
        //if (isexit)
        //{
        //    throw Oops.Bah("唯一标识Key不能重复");
        //}
        var dbentity = await db.Queryable<SysIpLimit>().FirstAsync(o => o.Id == input.Id.Value);
        input.Adapt(dbentity);

        //IpV4 验证\IP段是否存在于其它IP段中
        dbentity = await IpV4Validate(dbentity, input);

        return await db.UpdateAsync(dbentity);
    }


    /// <summary>
    /// 批量删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    [PgApiAction(name: "批量删除")]
    [OperationId(nameof(BatchDelete))]
    [HttpPost]
    public async Task<bool> BatchDelete(string ids)
    {
        return await db.FakeDeleteAsync<SysIpLimit>(ids);
    }

    /// <summary>
    /// 查询一条
    /// </summary>
    /// <param name="id"></param>
    [PgApiAction(name: "查询一条")]
    [OperationId(nameof(Get))]
    [HttpPost]
    public async Task<ApiSysIpLimitOut> Get(long id)
    {
        //var entity = await db.GetByIdAsync<SysIpLimit>(id);

        return await db.GetByIdAsync<SysIpLimit, ApiSysIpLimitOut>(id);
    }
    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    [PgApiAction(name: "分页查询")]
    [OperationId(nameof(GetList))]
    [HttpPost]
    public async Task<PagedList<ApiSysIpLimitOut>> GetList(ApiSysIpLimitQuery searchQuery)
    {
        var queryable = db.Queryable<SysIpLimit>();

        #region 筛选条件

        //开始日期
        if (searchQuery.StartDate.HasValue)
        {
            queryable = queryable.Where(o => o.CreationTime >= searchQuery.StartDate.Value);
        }
        //结束日期
        if (searchQuery.EndDate.HasValue)
        {
            var endtime = Convert.ToDateTime($"{searchQuery.EndDate.Value:yyyy-MM-dd} 23:59:59");
            queryable = queryable.Where(o => o.CreationTime <= endtime);
        }
        //关键词
        if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        {
            var kw = searchQuery.KeyWords?.Trim()?.ToLower() ?? "";
            queryable = queryable.Where(o => o.Remark.Contains(kw));
        }

        #endregion 筛选条件

        queryable = queryable.OrderByDescending(o => o.Id);
        var pagelist = await queryable.Select(o => new ApiSysIpLimitOut
        {
            Id = o.Id.SelectAll(),

            #region 自定义

            //IsEnableName = o.IsEnable?"是":"否"  ,//是否启用
            //IsDeletedName = o.IsDeleted?"是":"否"  ,//默认假删除

            #endregion 自定义
        })
            .Mapper(src =>
            {
            })
            .ToPagedListAsync(searchQuery.PageIndex, searchQuery.PageSize);

        //var pagelist= await pageResult.ToPagedListAsync<SysIpLimit, ApiSysIpLimitOut>(searchQuery.PageIndex, searchQuery.PageSize);

        return pagelist;
    }

    /// <summary>
    /// 设置状态
    /// </summary>
    /// <param name="id"></param>
    /// <param name="state"></param>
    /// <param name="field">字段名</param>
    /// <returns></returns>
    [PgApiAction(name: "设置状态")]
    [OperationId(nameof(SetState))]
    [HttpPost]
    public async Task<bool> SetState(long id, bool state, string field)
    {
        return await db.SetStateByIdAsync<SysIpLimit>(id, state, field);
    }

    /// <summary>
    /// IPV4 验证
    /// </summary>
    /// <param name="entity"></param>
    /// <param name="input"></param>
    /// <returns></returns>
    private async Task<SysIpLimit> IpV4Validate(SysIpLimit entity, ApiSysIpLimitInput input)
    {
        #region IpV4 验证\IP段是否存在于其它IP段中

        if (entity.IpType == SysIpType.IpV4)
        {
            var startIpValue = input.StartIp.IpToLong();
            var endIpValue = input.EndIp.IpToLong();


            entity.StartIpValue = startIpValue;
            entity.EndIpValue = endIpValue;

            #region 验证

            if (startIpValue > endIpValue) throw Oops.Bah("开始IP地址不能大于结束IP地址");

            #endregion

            var StartIp = await db.Queryable<SysIpLimit>().WhereIF(entity.Id > 0, o => o.Id != input.Id).FirstAsync(o => o.IsEnable == true &&
                startIpValue >= SqlFunc.ToInt64(o.StartIpValue) && startIpValue <= SqlFunc.ToInt64(o.EndIpValue));
            if (StartIp != null) throw Oops.Bah($"当前设置开始IP地址已存在,ID:{StartIp.Id} 地址：{StartIp.StartIp}-{StartIp.EndIp}");

            var EndIp = await db.Queryable<SysIpLimit>().WhereIF(entity.Id > 0, o => o.Id != input.Id).FirstAsync(o => o.IsEnable == true &&
                endIpValue >= SqlFunc.ToInt64(o.StartIpValue) && endIpValue <= SqlFunc.ToInt64(o.EndIpValue));
            if (EndIp != null) throw Oops.Bah($"当前设置结束IP地址已存在,ID:{EndIp.Id} 地址：{EndIp.StartIp}-{EndIp.EndIp}");
        }

        #endregion

        return entity;
    }
    private static bool IsValidIPv4(string ip)
    {
        // 正则表达式匹配IPv4地址
        string pattern = @"^((25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))\.){3}(25[0-5]|(2[0-4][0-9]|[01]?[0-9][0-9]?))$";
        return Regex.IsMatch(ip, pattern);
    }



}